package com.xj.exportfile.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xj.exportfile.enums.Excel;
import lombok.Data;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.*;

@Data
public class ExcelUtils<T> {

    /**
     * 实体对象
     */
    public Class<T> clazz;
    public List<Object[]> imagesField;


    public ExcelUtils(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 将结果写出到 Excel 中
     *
     * @param response
     * @param rows
     */
    public void export(HttpServletResponse response, List<T> rows) {
        ExcelWriter writer = ExcelUtil.getWriter("D:/tmp.xlsx");
        // 初始化
        init(writer);
        // 设置自动换行
        CellStyle cellStyle = writer.getCellStyle();
        cellStyle.setWrapText(true);
        // 写入内容
        writer.write(rows, true);
        // 插入图片
        insertImages(writer, rows);
        // 保存到本地
        writer.close();
        // 返回到前端
//        try (OutputStream out = response.getOutputStream()) {
//            response.setCharacterEncoding("UTF-8");
//            response.setContentType("application/xlsx");
//            writer.flush(out);
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            writer.close();
//        }
    }

    /**
     * 获取枚举中的内容进行初始化
     *
     * @param writer
     */
    public void init(ExcelWriter writer) {
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        // 获取字段名和枚举
        List<Object[]> fields = new ArrayList<>();
        for (Field field : tempFields) {
            if (field.isAnnotationPresent(Excel.class)) {
                Excel attr = field.getAnnotation(Excel.class);
                fields.add(new Object[]{field, attr});

            }
        }
        // 对字段继续排序
        fields.sort(Comparator.comparing(objects -> ((Excel) objects[1]).sort()));
        // 设置单元格样式
        imagesField = new ArrayList<>();
        for (int i = 0; i < fields.size(); i++) {
            Excel excel = (Excel) fields.get(i)[1];
            Field field = (Field) fields.get(i)[0];
            writer.setColumnWidth(i, excel.width().value());
            writer.addHeaderAlias(field.getName(), excel.name());
            if (excel.type() == Excel.Type.IMAGES) {
                imagesField.add(new Object[]{field, i});
            }
        }
        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
    }


    /**
     * 处理图片插入到 Excel 中
     * @param writer
     * @param rows
     */
    public void insertImages(ExcelWriter writer, List<T> rows) {
        if (imagesField.isEmpty()) {
            return;
        }
        Sheet sheet = writer.getSheet();
        Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();
        for (int i = 0; i < rows.size(); i++) {
            try {
                // 通过反射获取图片链接
                for (Object[] objects : imagesField) {
                    Field field = (Field) objects[0];
                    int index = (int) objects[1];
                    field.setAccessible(true);
                    String images = field.get(rows.get(i)).toString();
                    if (StrUtil.isEmpty(images)) {
                        continue;
                    }
                    String[] arr = images.split(",");
                    for (int j = 0; j < arr.length; j++) {
                        URL url = new URL(arr[j]);
                        InputStream inputStream = url.openConnection().getInputStream();
                        byte[] pictureData = IOUtils.readInputStream(inputStream);
                        ClientAnchor anchor = drawingPatriarch.createAnchor(0, 0, 0, 0,
                                index + j, i + 1, index + j + 1, i + 2);
                        // 添加图片
                        int pictureIndex = sheet.getWorkbook().addPicture(pictureData, HSSFWorkbook.PICTURE_TYPE_JPEG);
                        drawingPatriarch.createPicture(anchor, pictureIndex);
                        // 设置单元格宽高
                        sheet.setColumnWidth(index + j, 200 * 256 / 6);
                        Row row = sheet.getRow(i + 1);
                        row.setHeight((short) (200 * 20));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
